package jt.classic.app.dms.fileupload;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jt.classic.app.dms.DmsManager;
import jt.classic.system.ISystem;
import jt.classic.system.ISystemException;
import jt.classic.system.SimpleAction;
import jt.classic.system.database.SystemDataSource;
import jt.classic.system.database.SystemDataSourceException;
import jt.classic.system.object.IObject;
import jt.classic.system.object.ObjectManager;
import jt.classic.system.user.IUser;
import jt.classic.system.wordbook.WordBookInitializtion;
import jt.classic.system.wordbook.XWordbookMain;
import net.sf.json.JSONObject;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.limp.basework.Table;
import org.limp.basework.console.XSystemConfig;
import org.limp.basework.impl.CommonBean4HSQ;
import org.limp.mine.annex.AnnexException;
import org.limp.mine.annex.AnnexItem;
import org.limp.mine.annex.AnnexItemImpl;
import org.limp.mine.annex.AttFileItem;
import org.limp.mine.annex.AttFileItemImpl;
import org.limp.mine.annex.transactor.AnnexTransactor;
import org.limp.mine.annex.transactor.AnnexTransactorException;


/**
 * 文件上传action
 * @author lvt
 *
 */
public class FileUploadAction extends SimpleAction {
    /**
     * 上传文件
     * @param mapping
     * @param form
     * @param request
     * @param response
     * @throws Exception
     */
    public void upload(ActionMapping mapping, ActionForm form,
        HttpServletRequest request, HttpServletResponse response)
        throws Exception {
        Connection conn = null;
        IUser user = ISystem.getSessionUser(request);
        SystemDataSource ds = SystemDataSource.getInstance();
        String filename = null;
        String fileId = null;
        String currentfolderid = request.getParameter("currentfolderid");

        try {
            conn = ds.getConnection();
        } catch (SystemDataSourceException e1) {
            e1.printStackTrace();
        }

        ObjectManager om = new ObjectManager(conn);

        DiskFileItemFactory factory = new DiskFileItemFactory();

        factory.setSizeThreshold(10240000);

        String base = "d:/upload";
        File file = new File(base);

        if (!(file.exists())) {
            file.mkdirs();
        }

        factory.setRepository(file);

        ServletFileUpload upload = new ServletFileUpload(factory);

        upload.setSizeMax(10002400000L);
        upload.setHeaderEncoding("UTF-8");

        try {
            //			AnnexItem annexItem  = (AnnexItem)param.get(org.limp.mine.annex.AnnexItem.ANNEX);
            //			FileItem item = annexItem.getFileItem("DocContent");
            List items = upload.parseRequest(request);
            FileItem item = null;

            for (int i = 0; i < items.size(); ++i) {
                item = (FileItem) items.get(i);

                if (item.isFormField()) {
                    String fieldName = item.getFieldName();

                    if (fieldName.equals("currentfolderid")) {
                        currentfolderid = item.getString();
                    }

                    if (fieldName.equals("filename")) {
                        filename = item.getString();
                        filename = java.net.URLDecoder.decode(filename, "UTF-8");
                    }

                    if (fieldName.equals("fileId")) {
                        fileId = item.getString();
                        fileId = java.net.URLDecoder.decode(fileId, "UTF-8");
                    }
                }
            }

            List idList = new ArrayList();

            for (int i = 0; i < items.size(); ++i) {
                item = (FileItem) items.get(i);

                if ((!(item.isFormField())) && (item.getName().length() > 0) &&
                        (fileId == null)) {
                    Map resultMap = addRecord(filename, item, conn, om, user,
                            currentfolderid);
                    idList.add(resultMap);
                } else if ((!(item.isFormField())) &&
                        (item.getName().length() > 0) && (fileId != null)) {
                    update(fileId, item, conn);
                }
            }

            Map m = new HashMap();
            m.put("success", "true");
            m.put("list", idList);
            outJson(m, response);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            response.getWriter().close();
            SystemDataSource.closeConnection(conn);
        }
    }

    /**
     * 添加记录
     * @param filename 文件名称
     * @param item
     * @param conn
     * @param om
     * @param user
     * @param currentfolderid 当前目录id
     * @return
     */
    private Map<String, String> addRecord(String filename, FileItem item,
        Connection conn, ObjectManager om, IUser user, String currentfolderid) {
        /* 初始化CommonBean4HSQ （生成一个空实例，手工初始化数据内容） */
        CommonBean4HSQ cbh;

        //对象id
        String id = null;

        //对应的文件表id
        String fileId = null;
        Map result = null;
        Map<String, String> resultMap = new HashMap<String, String>();
        DmsManager dm = new DmsManager(conn);

        String suffix = "";

        try {
            cbh = new CommonBean4HSQ(null);

            /* 设置对象名称 */
            if ((!"".equals(filename)) && (filename != null)) {
                String docType = item.getContentType();

                if ("application/msword".equals(docType)) {
                    suffix = "doc";
                } else if ("application/vnd.ms-powerpoint".equals(docType)) {
                    suffix = "ppt";
                } else if ("application/vnd.ms-excel".equals(docType)) {
                    suffix = "xls";
                } else {
                    suffix = "wps";
                }

                cbh.getResource().put("COL_FILENAME", filename + "." + suffix);
                cbh.getResource().put("COL_FILETYPE", suffix);
                cbh.getResource().put("oname", filename + "." + suffix);
            } else {
                cbh.getResource().put("COL_FILENAME", item.getName());
                cbh.getResource().put("oname", item.getName());

                String originalFilename = item.getName();
                suffix = (originalFilename.lastIndexOf(".") > -1)
                    ? originalFilename.substring(originalFilename.lastIndexOf(
                            ".") + 1) : "";
                cbh.getResource().put("COL_FILETYPE", suffix);
            }

            /* 设置其它内容 */
            cbh.getResource().put("COL_DIRECTORYID", currentfolderid);
            cbh.getResource().put("COL_FILESIZE", "" + (item.getSize() / 1024));
            cbh.getResource().put("COL_STATE", "00");
            cbh.getResource().put("COL_VERSION", "1.0");

            cbh.getResource().put("okey", "FILEINFO");

            cbh.getResource().put("ocreatorid", user.id());
            cbh.getResource().put("ocreatorname", user.iname());
            cbh.getResource().put("ounitid", user.igroup().id());
            cbh.getResource().put("ounitname", user.igroup().iname());
            cbh.getResource().put("ounitnumber", user.igroup().inumber());
            /* 设置文件实体内容 */
            // cbh.getResource().put(AnnexItem.ANNEX, annexItem);
            IObject obj = om.auto("FILEINFO", cbh);

            Table table = obj.iobject().itable("DOC_BVFABRYJMQ");
            result = ((Map) ((List) obj.icontent(table)).get(0));
            fileId = (String) result.get("PK_DOC_BVFABRYJMQ");
            dm.insertEvent(fileId, user.id(), user.iname(), "创建了文档",
                "FILEINFO", "1.0");
            resultMap.put("objId", id);
            resultMap.put("fileId", fileId);

            /*将文件扩展名自动添加到数据字典配置文件中*/
            XWordbookMain wbmain = XWordbookMain.getInstance();
            boolean rnt = wbmain.insertWordbookItem("fileext", suffix, suffix,
                    "");

            if (rnt) {
                /*重新加载数据字典配置文件*/
                WordBookInitializtion init = new WordBookInitializtion();
                init.load();
            }
        } catch (ISystemException e2) {
            e2.printStackTrace();
        } catch (AnnexException e3) {
            e3.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        // ---------------------------------
        /* 获取上传文件 */
        AttFileItem afitem = new AttFileItemImpl(item, this.charsetName);

        /* 上传文件Map */
        Map annexInfo = new HashMap();
        annexInfo.put("file1", afitem); // 其中fieldName为文件表单数据实体对应的formname。
                                       /* 待处理附件实例 */

        AnnexItem annexitem = new AnnexItemImpl(annexInfo);
        /* 设置附件关联表主键值 */
        annexitem.setObjectId((String) result.get("PK_DOC_BVFABRYJMQ"));
        /* 设置附件关联表名称 */
        annexitem.setObjectName("DOC_BVFABRYJMQ");

        /* 获取附件处理器 */
        String transactor = (String) XSystemConfig.config()
                                                  .getProperty(XSystemConfig.XSYSTEM_ANNEX_TRANSACTOR);
        AnnexTransactor trans;

        try {
            trans = (AnnexTransactor) Class.forName(transactor).newInstance();
            trans.needHelp(conn);

            String FREEHOME = (String) XSystemConfig.config()
                                                    .getProperty(XSystemConfig.XSYSTEM_ANNEX_FREEHOME);
            String RESTRICTHOME = (String) XSystemConfig.config()
                                                        .getProperty(XSystemConfig.XSYSTEM_ANNEX_RESTRICTHOME);
            String REALPATH = (String) XSystemConfig.config()
                                                    .getProperty(XSystemConfig.XSYSTEM_REALPATH);

            trans.setHome(REALPATH, RESTRICTHOME, FREEHOME);
            /* 保存附件 */
            trans.setFreeHome(true);
            trans.save(annexitem);

            conn.commit();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (AnnexTransactorException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }

            e.printStackTrace();
        }

        return resultMap;
    }

    /**
     * 更新文件内容
     * @param fileId 文件表id即fk_annex_id
     * @param item
     * @param conn
     */
    private void update(String fileId, FileItem item, Connection conn) {
        AttFileItem afitem = new AttFileItemImpl(item, "utf-8");

        /* 上传文件Map */
        Map annexInfo = new HashMap();
        annexInfo.put("file", afitem); // 其中fieldName为文件表单数据实体对应的formname。
                                       /* 待处理附件实例 */

        AnnexItem annexitem = new AnnexItemImpl(annexInfo);
        /* 设置附件关联表主键值 */
        annexitem.setObjectId(fileId);
        /* 设置附件关联表名称 */
        annexitem.setObjectName("DOC_BVFABRYJMQ");

        /* 获取附件处理器 */
        String transactor = (String) XSystemConfig.config()
                                                  .getProperty(XSystemConfig.XSYSTEM_ANNEX_TRANSACTOR);
        AnnexTransactor trans;

        try {
            trans = (AnnexTransactor) Class.forName(transactor).newInstance();
            trans.needHelp(conn);

            String FREEHOME = (String) XSystemConfig.config()
                                                    .getProperty(XSystemConfig.XSYSTEM_ANNEX_FREEHOME);
            String RESTRICTHOME = (String) XSystemConfig.config()
                                                        .getProperty(XSystemConfig.XSYSTEM_ANNEX_RESTRICTHOME);
            String REALPATH = (String) XSystemConfig.config()
                                                    .getProperty(XSystemConfig.XSYSTEM_REALPATH);

            trans.setHome(REALPATH, RESTRICTHOME, FREEHOME);
            //先删除原附件
            trans.delete("DOC_BVFABRYJMQ", fileId);
            /* 保存附件 */
            trans.setFreeHome(true);
            trans.save(annexitem);

            //更新文件大小
            DmsManager dm = new DmsManager(conn);
            dm.updateVersion(fileId, "1.0", (item.getSize() / 1024) + "");

            conn.commit();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (AnnexTransactorException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private void outJsonString(String str, HttpServletResponse response) {
        response.setContentType("text/javascript;charset=UTF-8");
        outString(str, response);
    }

    private void outJson(Object obj, HttpServletResponse response) {
        outJsonString(JSONObject.fromObject(obj).toString(), response);
    }

    private void outString(String str, HttpServletResponse response) {
        try {
            PrintWriter out = response.getWriter();
            // System.out.println(str);
            out.write(str);
        } catch (IOException e) {
        }
    }
}
